package com.yenlien.traceyun.common.utils;

import org.apache.http.*;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.CodingErrorAction;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import static org.apache.http.HttpHeaders.USER_AGENT;


public class HttpUtil {

    private final static Logger logger = LoggerFactory.getLogger(HttpUtil.class);


    /**
     * 从指定url获取数据
     *
     * @param url
     * @return
     * @throws GeneralException
     */
    public static String getDataFromUrl(String url) {
        String rev = null;
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpGet get = new HttpGet(url);
        CloseableHttpResponse response = null;
        try {
            //添加http头信息
            response = httpclient.execute(get);
            int code = response.getStatusLine().getStatusCode();
            if (code == 200) {
                rev = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
                return rev;
            } else {
                rev = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
                logger.info("code:{}", code);
                logger.info("response:{}", rev);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                get.releaseConnection();
                httpclient.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        return rev;
    }

    /**
     * 从指定url通过json string参数获取数据
     *
     * @param url
     * @param jsonStr
     * @return
     * @throws GeneralException
     */
    public static String getDataFromUrlWithJSON(String url, String jsonStr) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.addHeader("charset", "UTF-8");
            HttpEntity httpEntity = null;
            httpEntity = new StringEntity(jsonStr, "UTF-8");
            httpPost.setHeader("Content-Type", "application/json; charset=utf-8");
            httpPost.setEntity(httpEntity);
            CloseableHttpResponse response = httpClient.execute(httpPost);
            return EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
        } catch (Exception e) {
        } finally {
            //释放链接
            httpPost.releaseConnection();
            try {
                httpClient.close();
            } catch (IOException e) {
            }
        }
        return null;
    }

    /**
     * 从指定url通过json string参数获取数据
     *
     * @param url
     * @param jsonStr
     * @return
     * @throws GeneralException
     */
    public static String getDataFrom(String url, String jsonStr) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.addHeader("charset", "UTF-8");
            HttpEntity httpEntity = null;
            httpEntity = new StringEntity(jsonStr, "UTF-8");
            httpPost.setEntity(httpEntity);
            CloseableHttpResponse response = httpClient.execute(httpPost);
            return EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
        } catch (Exception e) {
        } finally {
            //释放链接
            httpPost.releaseConnection();
            try {
                httpClient.close();
            } catch (IOException e) {
            }
        }
        return null;
    }

    /**
     * post
     *
     * @param url
     * @param params
     * @return
     */
    public static String post(String url, Map<String, String> params) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpResponse response = null;
        try {
            if (params != null && params.size() > 0) {
                List<NameValuePair> nvps = new ArrayList<NameValuePair>();
                for (Entry<String, String> entry : params.entrySet()) {
                    nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
                httpPost.setEntity(new UrlEncodedFormEntity(nvps));
            }
            response = httpclient.execute(httpPost);
            int code = response.getStatusLine().getStatusCode();
            logger.info("url:{},status:{}", url, code);
            switch (code) {
                case 200:
                    HttpEntity entity = response.getEntity();
                    String result = EntityUtils.toString(entity);
                    EntityUtils.consume(entity);
                    return result;
            }
        } catch (Exception e) {
            logger.error("httpUtil->post:{},errorInfo:{}", url, e.getMessage());
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                logger.error("httpUtil->post:{},errorInfo:{}", url, e.getMessage());
            }
        }
        return null;
    }
    /**
     * post
     *
     * @param url
     * @param params
     * @return
     */
    public static String post1(String url, Map<String, Object> params) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpResponse response = null;
        try {
            if (params != null && params.size() > 0) {
                List<NameValuePair> nvps = new ArrayList<NameValuePair>();
                for (Entry<String, Object> entry : params.entrySet()) {
                    nvps.add(new BasicNameValuePair(entry.getKey(), (String) entry.getValue()));
                }
                httpPost.setEntity(new UrlEncodedFormEntity(nvps));
            }
            response = httpclient.execute(httpPost);
            int code = response.getStatusLine().getStatusCode();
            logger.info("url:{},status:{}", url, code);
            switch (code) {
                case 200:
                    HttpEntity entity = response.getEntity();
                    String result = EntityUtils.toString(entity);
                    EntityUtils.consume(entity);
                    return result;
            }
        } catch (Exception e) {
            logger.error("httpUtil->post:{},errorInfo:{}", url, e.getMessage());
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                logger.error("httpUtil->post:{},errorInfo:{}", url, e.getMessage());
            }
        }
        return null;
    }

    public static String post2(String url, Map<String, Object> params) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String result = null;

        try {
            HttpPost httpPost = new HttpPost(url);

            if (params != null && !params.isEmpty()) {
                List<NameValuePair> nvps = new ArrayList<>();
                for (Map.Entry<String, Object> entry : params.entrySet()) {
                    nvps.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
                }
                httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
            }

            response = httpClient.execute(httpPost);

            int statusCode = response.getStatusLine().getStatusCode();

            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                result = EntityUtils.toString(entity, "UTF-8");
            }

            return result;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpClient.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    public static String get(String url) {
        return get(url, null);
    }

    /**
     * @param url
     * @param params
     * @return
     */
    public static String get(String url, Map<String, String> params) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = null;
        try {
            if (params != null && params.size() > 0) {
                StringBuffer sbuf = new StringBuffer();
                for (Entry<String, String> entry : params.entrySet()) {
                    sbuf.append("&").append(entry.getKey()).append("=").append(entry.getValue());
                }
                url = url + "?" + sbuf.substring(1);
            }
            response = httpclient.execute(httpGet);
            int code = response.getStatusLine().getStatusCode();
            logger.info("url:{},status:{}", url, code);
            switch (code) {
                case 200:
                    HttpEntity entity = response.getEntity();
                    String result = EntityUtils.toString(entity);
                    EntityUtils.consume(entity);
                    return result;
            }
        } catch (IOException e) {
            logger.error("httpUtil->get:{},errorInfo:{}", url, e.getMessage());
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                logger.error("httpUtil->get:{},errorInfo:{}", url, e.getMessage());
            }
        }
        return null;
    }

    /**
     * @param url
     * @param params
     * @return
     */
    public static byte[] getFile(String url) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httpGet);
            int code = response.getStatusLine().getStatusCode();
            logger.info("url:{},status:{}", url, code);
            switch (code) {
                case 200:
                    HttpEntity entity = response.getEntity();
                    InputStream in = entity.getContent();
                    return FileUtil.getFileByte(in);
            }
        } catch (IOException e) {
            logger.error("httpUtil->get:{},errorInfo:{}", url, e.getMessage());
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                logger.error("httpUtil->get:{},errorInfo:{}", url, e.getMessage());
            }
        }
        return null;
    }

    public static void close(CloseableHttpClient httpclient, CloseableHttpResponse response) {
        try {
            if (httpclient != null) {
                httpclient.close();
            }
            if (response != null) {
                response.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 发送Http  Post请求，参数为map
     *
     * @param url
     * @param map
     */
    public static String sendPost(String url, Map<String, Object> map) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            //给参数赋值
            formparams.add(new BasicNameValuePair(entry.getKey(), (String) entry.getValue()));
        }
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
        HttpPost httppost = new HttpPost(url);
        httppost.setEntity(entity);
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httppost);
        } catch (IOException e) {
            e.printStackTrace();
        }
        HttpEntity entity1 = (HttpEntity) response.getEntity();
        String result = null;
        try {
            result = EntityUtils.toString((org.apache.http.HttpEntity) entity1);
        } catch (ParseException | IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 发送Http  Post请求，参数为json字符串, 把Cookie保存起来
     *
     * @param url     请求地址
     * @param jsonStr json字符串
     * @return
     */
    public static String sendPost(String url, String jsonStr) throws IOException {
        String result;

        // 设置entity
        StringEntity stringEntity = new StringEntity(jsonStr, Consts.UTF_8);
        stringEntity.setContentType("application/json");

        HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(stringEntity);

        try (CloseableHttpClient httpclient = getBuilder().build(); CloseableHttpResponse httpResponse = httpclient.execute(httpPost);) {
            HttpEntity httpEntity = httpResponse.getEntity();
            result = EntityUtils.toString(httpEntity);
        }
        return result;
    }

    public static HttpClientBuilder getBuilder() {
        List<Header> headers = new ArrayList<>();
        Header header = new BasicHeader("User-Agent", USER_AGENT);
        headers.add(header);
        return HttpClients.custom().setDefaultConnectionConfig(connectionConfig).setDefaultHeaders(headers).setDefaultRequestConfig(requestConfig);
    }

    // 超时设置
    public static final RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(50000)
            .setConnectionRequestTimeout(50000)
            .setSocketTimeout(50000)
            .build();

    // 编码设置
    public static final ConnectionConfig connectionConfig = ConnectionConfig.custom()
            .setMalformedInputAction(CodingErrorAction.IGNORE)
            .setUnmappableInputAction(CodingErrorAction.IGNORE)
            .setCharset(Consts.UTF_8)
            .build();

}


